Skip to content

Pin npipe round-trip and pipe lifecycle invariants#5216

Merged
samuv merged 2 commits intomainfrom
windows-pipe-test-hardening
May 8, 2026
Merged

Pin npipe round-trip and pipe lifecycle invariants#5216
samuv merged 2 commits intomainfrom
windows-pipe-test-hardening

Conversation

@samuv
Copy link
Copy Markdown
Contributor

@samuv samuv commented May 7, 2026

Summary

Follow-up to #5201 (review thread). Stacked on socker-windows; will rebase onto main once #5201 merges. Sibling to #5214 and #5215.

Adds three regression tests around the named-pipe transport that the original PR did not cover. None reproduce a live bug today; they pin invariants the named-pipe path implicitly relies on so a future change can't silently break them.

  • TestWriteReadServerInfo_NamedPipe (cross-platform) — closes the producer/consumer loop for the discovery file: an npipe:// URL written by socketURL must survive WriteServerInfo + ReadServerInfo without being mangled. The individual emit/parse pieces have their own tests; this one pins the seam.
  • TestSetupUnixSocket_NamedPipe_FirstInstanceWins (Windows-only) — asserts that two winio.ListenPipe calls on the same name fail the second time. winio sets FILE_FLAG_FIRST_PIPE_INSTANCE so two thv processes cannot bind the same pipe and race for traffic; if a future winio bump silently relaxed that, this test catches it before the discovery layer does in production.
  • TestCheckHealth_NamedPipe_HungServerCancelsOnContext (Windows-only) — covers the StateUnhealthy path: a peer that accepts connections but never responds must not wedge CheckHealth past the caller's context deadline. The existing success and not-found tests don't exercise this case.

Addresses inline review comments 3201085442 (round-trip), 3201085446 (first-instance-wins), and 3201085449 (hung-peer).

Type of change

  • Test coverage / regression hardening

Test plan

  • go test ./pkg/api/... ./pkg/server/discovery/... — green on macOS (round-trip and Unix tests).
  • task lint-fix — 0 issues.
  • GOOS=windows go vet and GOOS=windows go test -c -o /dev/null for both packages — both clean.
  • Manual go test -tags windows -run NamedPipe on a Windows host — pending; deferred to a reviewer with a Windows host. The Windows-only tests are guarded by build tags and do not run on macOS / Linux.

Does this introduce a user-facing change?

No.

Made with Cursor

@samuv samuv requested review from JAORMX and amirejaz as code owners May 7, 2026 13:11
@samuv samuv self-assigned this May 7, 2026
@github-actions github-actions Bot added the size/XS Extra small PR: < 100 lines changed label May 7, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.86%. Comparing base (a4d66b1) to head (f2d3692).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5216      +/-   ##
==========================================
+ Coverage   67.83%   67.86%   +0.02%     
==========================================
  Files         610      610              
  Lines       62405    62405              
==========================================
+ Hits        42332    42350      +18     
+ Misses      16895    16877      -18     
  Partials     3178     3178              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Base automatically changed from socker-windows to main May 7, 2026 13:42
@samuv samuv force-pushed the windows-pipe-test-hardening branch from a9a8b72 to fc80b10 Compare May 8, 2026 11:40
@github-actions github-actions Bot added size/M Medium PR: 300-599 lines changed and removed size/XS Extra small PR: < 100 lines changed labels May 8, 2026
Add three regression tests around the named-pipe transport that
the original PR did not cover. None of these reproduce live bugs
today; they pin invariants the named-pipe path implicitly relies
on so a future change can't silently break them.

TestWriteReadServerInfo_NamedPipe (cross-platform) closes the
producer/consumer loop for the discovery file: an npipe:// URL
written by socketURL must survive WriteServerInfo + ReadServerInfo
without being mangled. The individual emit/parse pieces have
their own tests; this one pins the seam.

TestSetupUnixSocket_NamedPipe_FirstInstanceWins (Windows-only)
asserts that two ListenPipe calls on the same name fail the
second time. winio sets FILE_FLAG_FIRST_PIPE_INSTANCE so that
two thv processes cannot bind the same pipe and race for traffic;
if a future winio bump silently relaxed that, this test catches
it before the discovery layer does in production.

TestCheckHealth_NamedPipe_HungServerCancelsOnContext
(Windows-only) covers the StateUnhealthy path: a peer that
accepts connections but never responds must not wedge
CheckHealth past the caller's context deadline. The existing
success and not-found tests don't exercise this case.

Co-authored-by: Cursor <cursoragent@cursor.com>
@samuv samuv force-pushed the windows-pipe-test-hardening branch from fc80b10 to f88804b Compare May 8, 2026 11:43
@github-actions github-actions Bot added size/XS Extra small PR: < 100 lines changed and removed size/M Medium PR: 300-599 lines changed size/XS Extra small PR: < 100 lines changed labels May 8, 2026
Copy link
Copy Markdown
Member

@aponcedeleonch aponcedeleonch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two comments on the new tests.

Comment thread pkg/server/discovery/health_windows_test.go
Comment thread pkg/api/socket_windows_test.go Outdated
TestCheckHealth_NamedPipe_HungServerCancelsOnContext registered
t.Cleanup from inside the Accept loop goroutine. t.Cleanup is
documented to be called from the test goroutine; a registration
that lands after the test body returns can panic with "Log in
goroutine after Test has completed" or be silently dropped. The
test happened to work because the dial CheckHealth makes accepts
before the test body returns, but correctness was load-bearing on
that timing.

Pre-register a single t.Cleanup from the test body that closes
every accepted conn under a mutex, and have the goroutine append
to that slice instead of touching t. Listener cleanup runs in
LIFO order before the conn-close, which unblocks the goroutine's
Accept first so the slice is stable by the time we close it.

Drop the dead "if second != nil { Close }" branch in
TestSetupUnixSocket_NamedPipe_FirstInstanceWins: setupUnixSocket
returns (nil, err) on the named-pipe failure path, so the guard
can never be entered. Replace with a comment so the next reader
does not re-introduce it.

Addresses review on #5216.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added size/S Small PR: 100-299 lines changed and removed size/XS Extra small PR: < 100 lines changed labels May 8, 2026
Copy link
Copy Markdown
Member

@aponcedeleonch aponcedeleonch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both review comments addressed cleanly. The mutex-guarded slice + pre-registered t.Cleanup matches the suggested rewrite, and the LIFO ordering note in the commit message is a nice touch. LGTM.

@samuv samuv merged commit e943660 into main May 8, 2026
48 checks passed
@samuv samuv deleted the windows-pipe-test-hardening branch May 8, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/S Small PR: 100-299 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants